package org.room402.chat.process;

import cn.hutool.json.JSONUtil;
import lombok.RequiredArgsConstructor;
import org.reactivestreams.Publisher;
import org.room402.constant.chat.MessageAction;
import org.room402.entity.chat.ChatPool;
import org.room402.entity.chat.MessageEvent;
import org.room402.entity.chat.UserSession;
import org.room402.framework.chat.container.ChatPoolContainer;
import org.room402.framework.chat.container.UserSessionContext;
import org.room402.utile.chat.FastChatUtil;
import org.springframework.stereotype.Component;
import org.springframework.web.reactive.socket.WebSocketSession;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;

/**
 * @author Gong.Yang
 */
@Component
@RequiredArgsConstructor
public class InvitePoolEventProcess implements MessageProcess {
    private final ChatPoolContainer chatPoolContainer;
    private final UserSessionContext userSessionContext;

    @Override
    public boolean actionMatch(MessageEvent event, WebSocketSession session) {
        return MessageAction.pool_invite.equals(event.getAction());
    }

    @Override
    public boolean rejectMatch(MessageEvent event, WebSocketSession session) {
        return chatPoolContainer.isInPool(event.getContent(), userSessionContext.validByUid(event.getTargetId()));
    }

    @Override
    public Publisher<Void> process(MessageEvent event, WebSocketSession session) {
        UserSession targetUser = userSessionContext.getByUid(event.getTargetId());
        ChatPool chatPool = chatPoolContainer.inPool(event.getContent(), targetUser);
        return Flux.fromIterable(chatPool.getMembers())
                .map(userInfoView -> userSessionContext.getByUid(userInfoView.getId()))
                .flatMap(poolUser -> {
                    WebSocketSession targetSession = poolUser.getSession();
                    MessageEvent message = MessageEvent.form(chatPool.getId(), poolUser.getId(), MessageAction.pool_update, chatPool);
                    return targetSession.send(Mono.just(targetSession.textMessage(JSONUtil.toJsonStr(message))));
                });
    }

    @Override
    public Publisher<Void> reject(MessageEvent event, WebSocketSession session) {
        UserSession bySid = userSessionContext.getBySid(session.getId());
        return FastChatUtil.reject(bySid, "用户已在聊天池内");
    }
}
